// WxMiniSubscribeServiceImpl.java
package com.baoyouqun.API.push.mini;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baoyouqun.API.push.WechatConstant;
import com.baoyouqun.base.BusinessException;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class WxMiniSubscribeServiceImpl implements WxMiniSubscribeService {

    @Resource
    private WxMiniPush wxMiniPush;
    @Resource
    private RestTemplate restTemplate;


    @Override
    public void pushSubscribeMessage(List<String> openids, Map<String, Object> data) {
        if (CollUtil.isEmpty(openids)) {
            log.warn("小程序订阅消息推送失败：openid列表为空");
            return;
        }

        // 1. 获取小程序access_token（独立缓存，与服务号区分）
        String accessToken = getMiniAccessToken();

        // 2. 构建推送URL
        String pushUrl = WechatConstant.MINI_SUBSCRIBE_MESSAGE_URL.replace("ACCESS_TOKEN", accessToken);

        // 3. 向每个openid推送消息
        for (String openid : openids) {
            try {
                Map<String, Object> message = buildSubscribeMessage(openid, data);
                String result = restTemplate.postForObject(pushUrl, message, String.class);
                log.info("小程序订阅消息推送结果：{}，openid：{}", result, openid);

                // 处理错误响应
                JSONObject resultMap = JSONUtil.parseObj(result);
                if (!"0".equals(resultMap.get("errcode").toString())) {
                    log.error("小程序订阅消息推送失败：{}，openid：{}", result, openid);
                }
            } catch (Exception e) {
                log.error("小程序订阅消息推送异常，openid：{}", openid, e);
            }
        }
    }

    /**
     * 获取小程序access_token（缓存110分钟，避免过期）
     */
    private String getMiniAccessToken() {
        // 缓存key（与服务号区分，加上mini标识）
        String cacheKey = "wechat:mini:access_token:" + wxMiniPush.getAppId();

        // 从缓存获取
        Object cacheToken = StpUtil.getSession().getString(cacheKey);
        if (cacheToken != null) {
            return cacheToken.toString();
        }

        // 缓存未命中，调用微信接口获取
        String url = WechatConstant.ACCESS_TOKEN_URL
                .replace("APPID", wxMiniPush.getAppId())
                .replace("SECRET", wxMiniPush.getSecret());

        String result = restTemplate.getForObject(url, String.class);
        JSONObject resultMap = JSONUtil.parseObj(result);

        // 处理接口错误
        if (resultMap.containsKey("errcode") && !"0".equals(resultMap.get("errcode").toString())) {
            log.error("获取小程序access_token失败：{}", result);
            throw new BusinessException("小程序接口错误：" + resultMap.get("errmsg"));
        }

        // 缓存access_token
        String accessToken = resultMap.get("access_token").toString();
        StpUtil.getSession().set(cacheKey, accessToken);
        return accessToken;
    }

    /**
     * 构建小程序订阅消息体
     *
     * @param openid 接收者小程序openid
     * @param data   模板数据（格式：{ "字段名": { "value": "内容" } }）
     */
    private Map<String, Object> buildSubscribeMessage(String openid, Map<String, Object> data) {
        Map<String, Object> message = new HashMap<>();
        message.put("touser", openid); // 接收者openid
        message.put("template_id", wxMiniPush.getSubscribeTemplateId()); // 小程序订阅模板ID
        message.put("page", wxMiniPush.getPagePath()); // 点击跳转页面
        message.put("data", data); // 模板数据（需与小程序模板字段匹配）
        return message;
    }
}